<!-- demo1.vue -->
<template>
  <view class="chart-box" :style="[styObj]">
    <!-- 进度条部分 -->
    <view class="outer-box">
      <view class="inner-box">
        <!-- <div class="pointer-box"></div> -->
      </view>
    </view>
    <!-- 插槽内容 -->
    <view class="slot-content">
      <slot></slot>
    </view>
  </view>
</template>
<script>
export default {
  name:'circle-chart',
  props: {
    rate: {
      type: Number,
      default: 0,
    },
    config: {
      type: Object,
      default: () => {
        return {};
      },
    },
  },
  computed: {
    styObj() {
      let rate = 0;
      if (this.rate <= 0) {
        rate = 0;
      } else if (this.rate >= 1) {
        rate = 1;
      } else {
        rate = this.rate;
      }
      let endPos = `${rate*100}%`;
      let obj = Object.assign({}, this.defaultConfig, this.config);
      let rotate = `rotate(${360 * rate}deg)`;
      let chartRotate = obj.clockwise ? "rotateY(0deg)" : "rotateY(180deg)";
      let showEyes = obj.showEyes ? 1 : 0;
      return {
        "--background-image": `conic-gradient(${obj.startColor} 0%, ${obj.endColor} ${endPos}, transparent ${endPos})`,
        "--border-width": obj.borderWidth,
        "--dot-width": obj.circleSize,
        "--pointer-rotate": rotate,
        "--background-color": obj.borderBackground,
        "--center-gap-bg": obj.centerCircleBg,
        "--circle-color": obj.circleColor,
        "--clockwise-wise": chartRotate,
        "--show-eyes": showEyes,
        "--eyes-size": obj.eyesSize,
        "--start-color": obj.startColor,
        "--width": obj.width,
        "--height": obj.height,
      };
    },
  },
  data() {
    return {
      /* 此配置下所有属性均可在config中进行覆盖，实现个性化配置 */
      defaultConfig: {
        borderWidth: "8px", // 描边宽度
        borderBackground: "#E5E4EB", // 描边背景颜色
        circleSize: "12px", // 结尾处圆点直径
        circleColor: "#2ec4a7", // 结尾处圆点颜色
        startColor: "#d5f4ee", // 进度条起始颜色
        endColor: "#2ec4a7", // 进度条结束颜色
        centerCircleBg: "#fff", // 中间空心圆背景
        clockwise: true, // 是否顺时针
        showEyes: false, // 是否显示结尾处小眼睛
        eyesSize: "8px", // 结尾处小眼睛大小
      },
    };
  },
};
</script>
<style scoped lang="scss">
.chart-box {
  position: relative;
  width: var(--width);
  height: var(--height);
}
/* 核心代码、控制进度条样式及进度 */
.outer-box {
  width: 100%;
  height: 100%;
  border-radius: 50%;
  box-sizing: border-box;
  background-color: var(--background-color);
  background-image: var(--background-image);
  padding: var(--border-width);
  transform: var(--clockwise-wise);
}
/* 开始处增加一个圆形端点, 模拟圆角效果 */
.outer-box::after {
  content: "";
  width: var(--border-width);
  height: var(--border-width);
  border-radius: 50%;
  position: absolute;
  left: 50%;
  top: 0;
  transform: translateX(-50%);
  background: var(--start-color);
}
/* 中间添加一个和背景色一样的圆圈 */
.inner-box {
  position: relative;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  background: var(--center-gap-bg);
}
/* 指示针 */
.pointer-box {
  position: absolute;
  left: 50%;
  top: calc(0px - var(--border-width) / 2);
  bottom: calc(0px - var(--border-width) / 2);
  z-index: 1;
  transform-origin: center center;
  transform: var(--pointer-rotate);
}
/* 指示针的头部添加一个小圆点 */
.pointer-box::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 0;
  width: var(--dot-width);
  height: var(--dot-width);
  border-radius: 50%;
  background: var(--circle-color);
  transform: translate(-50%, -50%);
}
/* 进度条结尾处添加一个小眼睛，背景白色 */
.pointer-box::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 0;
  width: var(--eyes-size);
  height: var(--eyes-size);
  border-radius: 50%;
  background: #fff;
  transform: translate(-50%, -50%);
  z-index: 1;
  opacity: var(--show-eyes);
}
/* 插槽内容样式 */
.slot-content {
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
}
</style>
